;;;; Copyright 2009 Peter von Etter

;;;; This file is part of Autoproject

;;;; Autoproject is free software: you can redistribute it and/or
;;;; modify it under the terms of the GNU Lesser General Public
;;;; License as published by the Free Software Foundation, either
;;;; version 3 of the License, or (at your option) any later version.
;;;;
;;;; Autoproject is distributed in the hope that it will be useful,
;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
;;;; Lesser General Public License for more details.
;;;;
;;;; You should have received a copy of the GNU Lesser General Public
;;;; License along with Autoproject.  If not, see
;;;; <http://www.gnu.org/licenses/>.

(in-package #:autoproject.crud)

(defun sqlify (name &optional table)
  (if table
      (format nil "~A.~A"
              (substitute #\_ #\- (string-downcase (string table)))
              (substitute #\_ #\- (string-downcase (string name))))
      (substitute #\_ #\- (string-downcase (string name)))))

(defun lispify (name)
  (substitute #\- #\_ (string-upcase (string name))))

(defun symbolicate (name)
  (intern name))


;; Escape manually, so we don't have to depend on cl-ppcre

(labels ((count-escapes (s)
           (loop :with k = 0
                 :with len = 0
                 :for i :across s
                 :when (or (eql i #\\)
                           (eql i #\'))
                 :do (incf k)
                 :do (incf len)            
                 :finally (return (values k len))))
  
         (escape (s)
           (multiple-value-bind (escapes len)
               (count-escapes s)
             (let* ((esc-len (+ escapes len 2))
                    (esc (make-string esc-len)))
               (setf (aref esc 0) #\')
               (setf (aref esc (1- esc-len)) #\')
               (loop :for esc-i :from 1
                     :for i :from 0 :to (1- len)
                     :when (or (eql (aref s i) #\\)
                               (eql (aref s i) #\'))
                     :do (progn 
                           (setf (aref esc esc-i) (aref s i))
                           (incf esc-i))
                     :do (setf (aref esc esc-i) (aref s i)))
               esc))))
                 
  (defun database-format-value (thing)
    (cond ((stringp thing)
           (escape thing)
           #+nil
           (format nil "'~A'"
                   (cl-ppcre:regex-replace-all
                    "\\" (cl-ppcre:regex-replace-all
                          "'" thing "''")
                    "\\\\\\")))
          ((null thing)
           "NULL")

          ((floatp thing)
           (format nil "'~F'" thing))
         
          ((numberp thing) (princ-to-string thing))
          (t (format nil "'~A'" thing)))))

(defun remove-props (list prop-value &key (test #'eq))
  (loop :for (a b) :on list :by #'cddr
     :unless (funcall test b prop-value)
     :collect a :and :collect b))

(defun remove-nil-props (list)
  (remove-props list nil))

